package com.dy.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dy.common.R;
import com.dy.common.RedisConstonts;
import com.dy.dto.DishDto;
import com.dy.dto.SetmealDto;
import com.dy.entity.Setmeal;
import com.dy.service.SetmealService;
import com.sun.media.jfxmedia.logging.Logger;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.websocket.server.PathParam;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Description: 套餐控制层
 */
@Slf4j
@RestController
@RequestMapping("/setmeal")
public class SetmealController {

    @Autowired
    private SetmealService setmealService;

    @Autowired
    private StringRedisTemplate strRedis;

    /**
     * @Author dy
     * @Description: 新增套餐  / 和套餐绑定的菜品
     */
    @PostMapping
    public R<String> save(@RequestBody SetmealDto setmealDto){
        return setmealService.saveSetmeal(setmealDto);
    }


    /**
     * @Author dy
     * @Description: 套餐分页查询
     */
    @GetMapping("/page")
    public R<Page> page(Integer page,Integer pageSize,String name){
        Page pageSetmeal = new Page(page,pageSize);
        //获取数据总数
        Long total = setmealService.getTotal(name);
        //获取 套餐分页查询数据
        List<SetmealDto> list = setmealService.getPageData((page-1)*pageSize,pageSize,name);
        pageSetmeal.setRecords(list);
        pageSetmeal.setTotal(total);
        return R.success(pageSetmeal);
    }


    /**
     * @Author dy
     * @Description: 删除套餐 + 对应套餐绑定的菜品信息
     */
    @DeleteMapping
    public R<String> delete(@RequestParam List<Long> ids){
        return setmealService.delSetmealAndDish(ids);
    }

    /**
     * @Author dy
     * @Description: 修改套餐 状态
     */
    @PostMapping("status/{status}")
    public R<String> updateStatus(@PathVariable("status")int status,@RequestParam List<Long> ids){
        return setmealService.updateStatus(status,ids);
    }

    /**
     * @Author dy
     * @Description:  根据id查询对应 套餐数据
     */
    @GetMapping("/{id}")
    public R<SetmealDto> getDtoById(@PathVariable("id") Long id){
        return setmealService.getDtoById(id);
    }

    /**
     * @Author dy
     * @Description:  修改套餐数据
     */
    @PutMapping
    public R<String> update(@RequestBody SetmealDto setmealDto){
        return setmealService.updateSetmeal(setmealDto);
    }


    @GetMapping("/list")
    public R<List<Setmeal>> list(Setmeal  setmeal){
                                    //setmeal：         套餐对应的分类ID
        String key = RedisConstonts.SETMEAL_LIST + setmeal.getCategoryId() + "_" + setmeal.getStatus();
        //查询Redis 看是否有缓存。           dish:915617651321_1   字符串+分类ID+状态
        String s = strRedis.opsForValue().get(key);
        //缓存命中，返回缓存数据
        if(StringUtils.isNotBlank(s)){
            log.info("缓存命中 分类id：{}" + LocalDateTime.now(),setmeal.getCategoryId() );
            return R.success(JSONUtil.toList(s, Setmeal.class));
        }

        //查找对应 分类的套餐集合
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();

        //添加分类条件
        queryWrapper.eq(setmeal.getCategoryId() != null,Setmeal::getCategoryId,setmeal.getCategoryId());
        //添加状态条件
        queryWrapper.eq(setmeal.getStatus() != null,Setmeal::getStatus,setmeal.getStatus());
        List<Setmeal> list = setmealService.list(queryWrapper);

        //解决缓存穿透
        if(CollectionUtil.isEmpty(list)){
            log.info("缓存穿透，分类id：{}",setmeal.getCategoryId());
            strRedis.opsForValue().set(
                    key,
                    "",
                    3, TimeUnit.MINUTES);
            return R.success(ListUtil.empty());
        }

        //将 从数据库查询到的数据存到redis
        String jsonStr = JSONUtil.toJsonStr(list);
        //加入缓存 过期时间 一小时
        log.info("缓存重建" + LocalDateTime.now());
        strRedis.opsForValue().set(
                key,
                jsonStr,
                1, TimeUnit.HOURS);

        return R.success(list);
    }
}
